<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>角色成员</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="privileges.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="user-manag.html">快退</a></td><td width="60%" align="center" valign="bottom">章18. 数据库角色和权限</td><td width="10%" align="right" valign="top"><a href="user-manag.html">快进</a></td><td width="10%" align="right" valign="top"><a href="perm-functions.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="ROLE-MEMBERSHIP">18.4. 角色成员</a></h1><a name="AEN22678"></a>
<p>把用户组合起来简化权限管理是个常用的便利方法：用这样的方法，权限可以赋予整个组，也可以对整个组撤消。在 PostgreSQL 里，这些事情是通过创建代表一个组的角色，然后赋予组角色的<i class="FIRSTTERM">成员</i>权限给独立的用户角色的方法实现的。</p>
<p>要设置一个组角色，首先创建角色：</p>
<pre class="SYNOPSIS">CREATE ROLE <tt class="REPLACEABLE"><i>name</i></tt>;</pre>
<p>一般作为组使用的角色不应当具有 <tt class="LITERAL">LOGIN</tt> 属性，虽然你可以设置它。</p>
<p>一旦组角色已经存在了，那么你就可以用 <a href="sql-grant.html"><i>GRANT</i></a> 和 <a href="sql-revoke.html"><i>REVOKE</i></a> 命令添加和撤消权限：</p>
<pre class="SYNOPSIS">GRANT <tt class="REPLACEABLE"><i>group_role</i></tt> TO <tt class="REPLACEABLE"><i>role1</i></tt>, ... ;
REVOKE <tt class="REPLACEABLE"><i>group_role</i></tt> FROM <tt class="REPLACEABLE"><i>role1</i></tt>, ... ;</pre>
<p>你还可以赋予成员权限给其它组角色(因为在组角色和非组角色之间没有实质的区别)。唯一的制约是你不能建立循环的成员关系。另外，不允许给 <tt class="LITERAL">PUBLIC</tt> 角色赋予成员权限。</p>
<p>一个组角色的成员可以用两种方法使用组角色的权限。首先，一个组的每个成员都可以明确用 <a href="sql-set-role.html"><i>SET ROLE</i></a> 临时"变成"该组的成员。在这个状态下，数据库会话具有该组角色的权限，而不是原始的登录角色权限，这个时候创建的数据库对象被认为是由组角色拥有，而不是登录角色。第二，拥有 <tt class="LITERAL">INHERIT</tt> 属性的角色成员自动具有它们所属组角色的权限。例如，假如我们做了下面的事情：</p>
<pre class="PROGRAMLISTING">CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;</pre>
<p>那么在以角色 <tt class="LITERAL">joe</tt> 连接之后，该数据库会话将立即拥有直接赋予 <tt class="LITERAL">joe</tt> 的权限加上任何赋予 <tt class="LITERAL">admin</tt> 的权限，因为 <tt class="LITERAL">joe</tt> "继承"了 <tt class="LITERAL">admin</tt> 的权限。不过，赋予 <tt class="LITERAL">wheel</tt> 的权限不可用，因为即使 <tt class="LITERAL">joe</tt> 是 <tt class="LITERAL">wheel</tt> 的一个间接成员，但该成员关系是通过 <tt class="LITERAL">admin</tt> 过来的，而该组有 <tt class="LITERAL">NOINHERIT</tt> 属性。在</p>
<pre class="PROGRAMLISTING">SET ROLE admin;</pre>
<p>之后，该会话将只拥有那些已赋予 <tt class="LITERAL">admin</tt> 的权限，而不包括那些已赋予 <tt class="LITERAL">joe</tt> 的权限。在</p>
<pre class="PROGRAMLISTING">SET ROLE wheel;</pre>
<p>之后，该会话将只能使用已赋予 <tt class="LITERAL">wheel</tt> 的权限，而不包括已赋予 <tt class="LITERAL">joe</tt> 或 <tt class="LITERAL">admin</tt> 的权限。原来的权限可以用下列之一恢复：</p>
<pre class="PROGRAMLISTING">SET ROLE joe;
SET ROLE NONE;
RESET ROLE;</pre>
<div class="NOTE">
<blockquote class="NOTE">
<p><b>【注意】</b><tt class="COMMAND">SET ROLE</tt> 命令总是允许选取任意登录角色直接或者间接所在的组角色。因此，在上面的例子里，我们没必要在变成 <tt class="LITERAL">wheel</tt> 之前先变成 <tt class="LITERAL">admin</tt> 。</p>
</blockquote>
</div>
<div class="NOTE">
<blockquote class="NOTE">
<p><b>【注意】</b>在 SQL 标准里，在用户和角色之间有明确的区别，并且用户并不会自动继承权限，而角色可以。这个行为在 PostgreSQL 里面可以通过给予那些当作 SQL 角色使用的角色以 <tt class="LITERAL">INHERIT</tt> 属性，而给予当作 SQL 用户使用的角色以 <tt class="LITERAL">NOINHERIT</tt> 属性来实现。不过，PostgreSQL 缺省是给予所有角色 <tt class="LITERAL">INHERIT</tt> 属性，目的是和 8.1 之前的版本向下兼容，那些版本里，用户总是能使用他们所在组被赋予的权限。</p>
</blockquote>
</div>
<p>角色属性 <tt class="LITERAL">LOGIN</tt>, <tt class="LITERAL">SUPERUSER</tt>, <tt class="LITERAL">CREATEDB</tt>, <tt class="LITERAL">CREATEROLE</tt> 可以被认为是特殊的权限，但是它们从来不会像数据库对象上的普通权限那样继承。你必须明确地 <tt class="COMMAND">SET ROLE</tt> 到一个特殊的角色，这个角色应该是拥有这些属性的角色，然后才能利用这些属性。继续上面的例子，我们也可以选择给 <tt class="LITERAL">admin</tt> 角色赋予 <tt class="LITERAL">CREATEDB</tt> 和 <tt class="LITERAL">CREATEROLE</tt> 权限。然后，以 <tt class="LITERAL">joe</tt> 连接的会话不会立即有这些权限，只有在 <tt class="COMMAND">SET ROLE admin</tt> 之后才有。</p>
<p>要删除一个组角色，用 <a href="sql-droprole.html"><i>DROP ROLE</i></a> 命令：</p>
<pre class="SYNOPSIS">DROP ROLE <tt class="REPLACEABLE"><i>name</i></tt>;</pre>
<p>任何在组角色里面的成员关系都会自动撤消(但是成员角色自己则不受影响)。不过，请注意任何组角色拥有的对象都必须首先删除或者赋予其它所有者；并且任何给该组角色赋予的权限都必须撤消。</p>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="privileges.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="perm-functions.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">权限</td><td width="34%" align="center" valign="top"><a href="user-manag.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">函数和触发器</td></tr>
</table>
</div>
</body></html>